package com.weilele.leisure.time.ui.module.main

import androidx.lifecycle.MutableLiveData
import com.weilele.leisure.time.base.BaseVideoViewModel
import com.weilele.leisure.time.bean.PageByIdBean
import com.weilele.leisure.time.bean.VideoListBean
import com.weilele.leisure.time.net.ApiInstance2
import com.weilele.leisure.time.ui.holder.HomeBannerHolder
import com.weilele.leisure.time.ui.holder.PlaceholderHolder
import com.weilele.leisure.time.ui.holder.SimpleTextTitleHolder
import com.weilele.leisure.time.ui.holder.VideoItemHolder
import com.weilele.mvvm.adapter.ignoreError
import com.weilele.mvvm.base.helper.PageHelper
import com.weilele.mvvm.base.helper.pageHelperData
import com.weilele.mvvm.base.helper.updatePageHelper
import com.weilele.mvvm.base.livedata.*
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.async
import kotlin.math.max

class MainViewModel : BaseVideoViewModel() {
    private val pageDataMap = hashMapOf<Int?, MutableLiveData<StatusData<PageHelper<Any,Any>>>>()
    fun getPageData(bean: PageByIdBean?): MutableLiveData<StatusData<PageHelper<Any,Any>>> {
        val vid = bean?.id
        val data = pageDataMap[vid]
        return if (data == null) {
            val newData = pageHelperData<Any>()
            pageDataMap[vid] = newData
            newData
        } else {
            data
        }
    }


    /**
     * 返回false，代表此次未请求数据
     */
    fun getVideos(pageBean: PageByIdBean?): Boolean {
        pageBean ?: return false
        val pageData = getPageData(pageBean)
        if (pageData.isRunning) {
            return false
        }
        if (pageData.isSuccess) {
            return false
        }
        val components = pageBean.components ?: return false
        pageData.runInCoroutineScope {
            val requestMap =
                hashMapOf<PageByIdBean, Deferred<MutableList<VideoListBean.RowsDTO>?>>()
            components.forEach {
                if (it.type == ITEM_TYPE_VIDEO_LIST ||
                    it.type == ITEM_TYPE_VIDEO_DRAG_LIST
                ) {
                    requestMap[it] = async {
                        val params = getParams(it.datas)
                        ignoreError { ApiInstance2.getVideos(params).result?.rows }
                    }
                }
            }
            for ((bean, results) in requestMap) {
                bean.videos = results.await()
            }
            val hasMore = components.lastOrNull()?.datas?.isPaging ?: false
            if (hasMore) {
                loadMoreParams[pageBean.id] = getParams(components.lastOrNull()?.datas)
            }
            pageData.updatePageHelper(
                0, pagesToAdapterDatas(pageBean), true, hasMore, null
            )
        }
        return true
    }

    /**
     * 加载更多
     */
    private val loadMoreParams = hashMapOf<Int, HashMap<String, Any?>?>()

    fun loadMore(pageBean: PageByIdBean?) {
        pageBean ?: return
        val params = loadMoreParams[pageBean.id] ?: return
        val pageData = getPageData(pageBean)
        if (pageData.isRunning) {
            return
        }
        val lastStart = params["start"] as Int
        val lastNum = params["num"] as Int
        val num = max(lastNum, 9)//一次最少加载9条数据
        params["start"] = lastStart + num
        params["num"] = num
        pageData.runInCoroutineScope(runIfSuccess = true) {
            val newDatas = ApiInstance2.getVideos(params).result?.rows?.toVideoItemBeans()
            val oldIndex = pageData.data?.currentPageIndex ?: 0
            val hasNextPage = !(newDatas.isNullOrEmpty() || newDatas.count() < num)
            pageData.updatePageHelper(oldIndex + 1, newDatas, false, hasNextPage, null)
        }
    }

    private fun getParams(data: PageByIdBean.DatasDTO?): HashMap<String, Any?> {
        data ?: return hashMapOf()
        val linkedHashMap = HashMap<String, Any?>()
        linkedHashMap["area"] = data.area
        linkedHashMap["by"] = data.by
        linkedHashMap["ext_type"] = data.ext_type
        linkedHashMap["hits_condition"] = data.hits_condition
        linkedHashMap["hits_type"] = data.hits_type
        linkedHashMap["hits_value"] = data.hits_value
        linkedHashMap["ids"] = data.ids
        linkedHashMap["lang"] = data.lang
        linkedHashMap["type"] = if (data.type == null) "" else data.type
        linkedHashMap["start"] = data.start
        linkedHashMap["num"] = data.num
        linkedHashMap["order"] = data.order
        linkedHashMap["lang"] = data.lang
        linkedHashMap["paging"] = data.isPaging
        linkedHashMap["rel"] = data.rel
        linkedHashMap["state"] = data.state
        linkedHashMap["tag"] = data.tag
        linkedHashMap["time"] = data.time
        linkedHashMap["timeadd"] = data.timeadd
        linkedHashMap["version"] = data.version
        linkedHashMap["year"] = data.year
        linkedHashMap["key"] = data.key
        linkedHashMap["mid"] = data.mid
        linkedHashMap["level"] = data.level
        return linkedHashMap
    }

    private fun MutableList<VideoListBean.RowsDTO>.toVideoItemBeans(): MutableList<Any> {
        return this.map {
            val video = it
            if (video.pic != null) {
                if (video.pic.startsWith("mac://")) {
                    video.pic = video.pic?.replace("mac://", "https://")
                }
            }
            VideoItemHolder.Bean(video)
        }.toMutableList()
    }

    /**
     * 请求的后台数据，转为适配器可以加载的数据
     */
    fun pagesToAdapterDatas(pageBean: PageByIdBean?): MutableList<Any> {
        val adapterDatas = mutableListOf<Any>()
        val items = pageBean?.components ?: return adapterDatas
        items.forEach {
            when (it.type) {
                ITEM_TYPE_BANNER -> {
                    adapterDatas.add(HomeBannerHolder.Bean(it))
                }
                ITEM_TYPE_SEARCH -> {

                }
                ITEM_TYPE_TAB_ITEM -> {
                }
                ITEM_TYPE_VIDEO_LIST, ITEM_TYPE_VIDEO_DRAG_LIST -> {
                    adapterDatas.add(SimpleTextTitleHolder.Bean(it.title, "", null))
                    val videos = it.videos
                    if (videos.isNullOrEmpty()) {
                        adapterDatas.add(PlaceholderHolder.Bean())
                    } else {
                        adapterDatas.addAll(videos.toVideoItemBeans())
                    }
                }
                ITEM_TYPE_AD -> {
                }
            }
        }
        return adapterDatas
    }
}